package com.mf.elephant.common.framework.service;

import com.mf.elephant.common.annotation.AutoFill;
import com.mf.elephant.common.framework.dao.IDao;
import com.mf.elephant.common.framework.dao.PageBean;
import com.mf.elephant.common.sso.LoginContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;

/**
 * Web通用Service实现类
 * User: zhaoming
 * Date: 2016-06-24
 * To change this template use File | Settings | File Templates.
 **/
public class WebGenericService<T extends Object> implements IService<T> {

    public Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private IDao<T> iDao;

    /**
     * 新增实体对象
     * @param entity 实体对象
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean insert(T entity){
        try{
            Field[] superFields = entity.getClass().getSuperclass().getDeclaredFields();
            for(Field field : superFields){
                AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                if(autoFillAnnotation != null){
                    field.setAccessible(true);
                    switch (autoFillAnnotation.value()){
                        case CREATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case CREATE_TIME:
                            field.set(entity, new Date());
                            break;
                        case UPDATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case UPDATE_TIME:
                            field.set(entity, new Date());
                            break;
                        default:
                            break;
                    }
                }
            }
            Field[] fields = entity.getClass().getDeclaredFields();
            for(Field field : fields){
                AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                if(autoFillAnnotation != null){
                    field.setAccessible(true);
                    switch (autoFillAnnotation.value()){
                        case CREATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case CREATE_TIME:
                            field.set(entity, new Date());
                            break;
                        case UPDATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case UPDATE_TIME:
                            field.set(entity, new Date());
                            break;
                        default:
                            break;
                    }
                }
            }
        } catch (IllegalAccessException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return iDao.insert(entity);
    }

    /**
     * 批量新增实体对象
     * @param entities 实体对象列表
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean batchInsert(List<T> entities){
        for(T entity : entities){
            try{
                Field[] superFields = entity.getClass().getSuperclass().getDeclaredFields();
                for(Field field : superFields){
                    AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                    if(autoFillAnnotation != null){
                        field.setAccessible(true);
                        switch (autoFillAnnotation.value()){
                            case CREATE_USER:
                                field.set(entity, LoginContext.getLoginUser().getUserCode());
                                break;
                            case CREATE_TIME:
                                field.set(entity, new Date());
                                break;
                            case UPDATE_USER:
                                field.set(entity, LoginContext.getLoginUser().getUserCode());
                                break;
                            case UPDATE_TIME:
                                field.set(entity, new Date());
                                break;
                            default:
                                break;
                        }
                    }
                }
                Field[] fields = entity.getClass().getDeclaredFields();
                for(Field field : fields){
                    AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                    if(autoFillAnnotation != null){
                        field.setAccessible(true);
                        switch (autoFillAnnotation.value()){
                            case CREATE_USER:
                                field.set(entity, LoginContext.getLoginUser().getUserCode());
                                break;
                            case CREATE_TIME:
                                field.set(entity, new Date());
                                break;
                            case UPDATE_USER:
                                field.set(entity, LoginContext.getLoginUser().getUserCode());
                                break;
                            case UPDATE_TIME:
                                field.set(entity, new Date());
                                break;
                            default:
                                break;
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
        }
        return iDao.batchInsert(entities);
    }

    /**
     * 根据主键修改实体对象
     * @param entity 实体对象
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean updateByPrimaryKey(T entity){
        try{
            Field[] superFields = entity.getClass().getSuperclass().getDeclaredFields();
            for(Field field : superFields){
                AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                if(autoFillAnnotation != null){
                    field.setAccessible(true);
                    switch (autoFillAnnotation.value()){
                        case UPDATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case UPDATE_TIME:
                            field.set(entity, new Date());
                            break;
                        default:
                            break;
                    }
                }
            }
            Field[] fields = entity.getClass().getDeclaredFields();
            for(Field field : fields){
                AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                if(autoFillAnnotation != null){
                    field.setAccessible(true);
                    switch (autoFillAnnotation.value()){
                        case UPDATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case UPDATE_TIME:
                            field.set(entity, new Date());
                            break;
                        default:
                            break;
                    }
                }
            }
        } catch (IllegalAccessException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return iDao.updateByPrimaryKey(entity);
    }

    /**
     * 根据主键删除实体对象(物理删除)
     * @param id 主键
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean deleteByPrimaryKey(Long id){
        return iDao.deleteByPrimaryKey(id);
    }

    /**
     * 根据主键删除实体对象(物理删除)
     * @param entity 实体对象
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean deleteByPrimaryKey(T entity){
        return iDao.deleteByPrimaryKey(entity);
    }

    /**
     * 根据主键批量删除实体对象
     * @param entities 实体对象列表
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean deleteByPrimaryKeys(List<T> entities){
        return iDao.deleteByPrimaryKeys(entities);
    }

    /**
     * 根据主键删除实体对象(逻辑删除)
     * @param entity 实体对象
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean deleteByPrimaryKeyLogically(T entity){
        try{
            Field[] superFields = entity.getClass().getSuperclass().getDeclaredFields();
            for(Field field : superFields){
                AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                if(autoFillAnnotation != null){
                    field.setAccessible(true);
                    switch (autoFillAnnotation.value()){
                        case UPDATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case UPDATE_TIME:
                            field.set(entity, new Date());
                            break;
                        default:
                            break;
                    }
                }
            }
            Field[] fields = entity.getClass().getDeclaredFields();
            for(Field field : fields){
                AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                if(autoFillAnnotation != null){
                    field.setAccessible(true);
                    switch (autoFillAnnotation.value()){
                        case UPDATE_USER:
                            field.set(entity, LoginContext.getLoginUser().getUserCode());
                            break;
                        case UPDATE_TIME:
                            field.set(entity, new Date());
                            break;
                        default:
                            break;
                    }
                }
            }
        } catch (IllegalAccessException e) {
            logger.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return iDao.deleteByPrimaryKeyLogically(entity);
    }

    /**
     * 根据主键批量删除实体对象
     * @param entities 实体对象列表
     * @return 执行结果 (true:成功; false:失败)
     */
    @Transactional
    public boolean deleteByPrimaryKeysLogically(List<T> entities){
        for(T entity : entities){
            try{
                Field[] superFields = entity.getClass().getSuperclass().getDeclaredFields();
                for(Field field : superFields){
                    AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                    if(autoFillAnnotation != null){
                        field.setAccessible(true);
                        switch (autoFillAnnotation.value()){
                            case UPDATE_USER:
                                field.set(entity, LoginContext.getLoginUser().getUserCode());
                                break;
                            case UPDATE_TIME:
                                field.set(entity, new Date());
                                break;
                            default:
                                break;
                        }
                    }
                }
                Field[] fields = entity.getClass().getDeclaredFields();
                for(Field field : fields){
                    AutoFill autoFillAnnotation = field.getAnnotation(AutoFill.class);
                    if(autoFillAnnotation != null){
                        field.setAccessible(true);
                        switch (autoFillAnnotation.value()){
                            case UPDATE_USER:
                                field.set(entity, LoginContext.getLoginUser().getUserCode());
                                break;
                            case UPDATE_TIME:
                                field.set(entity, new Date());
                                break;
                            default:
                                break;
                        }
                    }
                }
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
        }
        return iDao.deleteByPrimaryKeysLogically(entities);
    }

    /**
     * 根据主键查询实体对象
     * @param id 主键
     * @return 实体对象
     */
    public T selectByPrimaryKey(Long id){
        return iDao.selectByPrimaryKey(id);
    }

    /**
     * 根据主键查询实体对象
     * @param entity 实体对象
     * @return 实体对象
     */
    public T selectByPrimaryKey(T entity){
        return iDao.selectByPrimaryKey(entity);
    }

    /**
     * 根据条件查询实体对象列表
     * @param entity 实体对象
     * @return 实体对象列表
     */
    public List<T> selectByCondition(T entity) {
        return iDao.selectByCondition(entity);
    }

    /**
     * 根据条件查询实体对象数量
     * @param entity 实体对象
     * @return 实体对象列表
     */
    public Integer selectByConditionCount(T entity) {
        return iDao.selectByConditionCount(entity);
    }

    /**
     * 分页查询实体对象列表
     * @param pageBean 分页实体
     * @param entity 实体对象
     * @return 实体对象列表
     */
    public PageBean<T> pageQuery(PageBean pageBean, T entity){
        return iDao.pageQuery(pageBean, entity);
    }

}
